package com.engine.api.gdyjs.util;

import com.engine.api.gdyjs.entity.ZczjStatInfo;
import com.engine.api.gdyjs.entity.MonthlyZcrkStat;
import com.engine.api.gdyjs.entity.AnnualZcrkStat;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 资产折旧统计工具类
 * 提供年度和月度资产折旧统计功能
 */
public class ZjStatUtil {
    private static final DateTimeFormatter DATE_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd");

    // 缓存日期解析结果，避免重复解析
    private static final Map<String, LocalDate> DATE_CACHE = new ConcurrentHashMap<>();

    /**
     * 获取完整的折旧统计报告（年度+月度）
     * @param list 资产折旧统计列表
     * @return 包含年度和月度折旧统计的Map
     */
    public static Map<String, Object> getCurrentPeriodFinancialReport(List<ZczjStatInfo> list) {
        Map<String, Object> report = new HashMap<>();

        // 年度折旧统计
        report.put("annualStats", getAnnualDepreciationStatistics(list));

        // 月度折旧统计
        report.put("monthlyStats", getMonthlyDepreciationStatistics(list));

        // 统计汇总信息
//        report.put("summary", getDepreciationSummaryInfo(list));

        return report;
    }

    /**
     * 年度折旧统计：追溯历史8年数据（净值）
     * @param list 资产折旧统计列表
     * @return 按年度分组的折旧统计结果列表
     */
    public static List<AnnualZcrkStat> getAnnualDepreciationStatistics(List<ZczjStatInfo> list) {
        // 空值检查
        if (list == null || list.isEmpty()) {
            return createEmptyAnnualStats();
        }

        // 过滤有效数据
        List<ZczjStatInfo> filteredList = list.stream()
                .filter(ZjStatUtil::isValidAssetDepreciation)
                .collect(Collectors.toList());

        int currentYear = LocalDate.now().getYear();
        // 计算起始年度（当前年度往前推8年）
        int startYear = currentYear - 8;

        // 按年度分组统计，取每年12月份的数据
        Map<Integer, AnnualZcrkStat> resultMap = new HashMap<>();

        for (int year = startYear; year < currentYear; year++) {
            // 构建12月份的YearMonth
            YearMonth decemberYM = YearMonth.of(year, 12);

            // 查找该年12月份的数据
            Optional<ZczjStatInfo> decemberData = filteredList.stream()
                    .filter(asset -> {
                        try {
                            LocalDate gxrq = parseDate(asset.getGxrq());
                            YearMonth assetYM = YearMonth.from(gxrq);
                            return assetYM.equals(decemberYM);
                        } catch (Exception e) {
                            return false;
                        }
                    })
                    .max(Comparator.comparing(asset -> parseDate(asset.getGxrq())));

            if (decemberData.isPresent()) {
                ZczjStatInfo asset = decemberData.get();
                BigDecimal netValue = asset.getZcjz() != null ? asset.getZcjz() : BigDecimal.ZERO;
                resultMap.put(year, new AnnualZcrkStat(year, 0, netValue));
            } else {
                resultMap.put(year, new AnnualZcrkStat(year, 0, BigDecimal.ZERO));
            }
        }

        // 确保所有年度都有数据（即使为0）
        List<AnnualZcrkStat> result = new ArrayList<>();
        for (int year = startYear; year < currentYear; year++) {
            if (resultMap.containsKey(year)) {
                AnnualZcrkStat stat = resultMap.get(year);
                if (stat != null) {
                    result.add(stat);
                } else {
                    result.add(new AnnualZcrkStat(year, 0, BigDecimal.ZERO));
                }
            } else {
                result.add(new AnnualZcrkStat(year, 0, BigDecimal.ZERO));
            }
        }

        // 按年份排序
        return result.stream()
                .filter(Objects::nonNull)
                .sorted(Comparator.comparing(AnnualZcrkStat::getYear))
                .collect(Collectors.toList());
    }

    /**
     * 月度折旧统计：追溯历史12个月数据（净值）
     * @param list 资产折旧统计列表
     * @return 按月度分组的折旧统计结果列表
     */
    public static List<MonthlyZcrkStat> getMonthlyDepreciationStatistics(List<ZczjStatInfo> list) {
        // 空值检查
        if (list == null || list.isEmpty()) {
            return createEmptyMonthlyStats();
        }

        // 过滤有效数据
        List<ZczjStatInfo> filteredList = list.stream()
                .filter(ZjStatUtil::isValidAssetDepreciation)
                .collect(Collectors.toList());

        YearMonth currentYearMonth = YearMonth.now();
        // 计算起始年月（当前年月往前推11个月）
        YearMonth startYM = currentYearMonth.minusMonths(11);

        // 按月度分组统计净值
        Map<String, MonthlyZcrkStat> resultMap = filteredList.stream()
                .filter(asset -> {
                    try {
                        LocalDate gxrq = parseDate(asset.getGxrq());
                        YearMonth assetYM = YearMonth.from(gxrq);
                        return !assetYM.isBefore(startYM) && !assetYM.isAfter(currentYearMonth);
                    } catch (Exception e) {
                        return false;
                    }
                })
                .collect(Collectors.groupingBy(
                        asset -> {
                            try {
                                return YearMonth.from(parseDate(asset.getGxrq())).toString();
                            } catch (Exception e) {
                                return "invalid";
                            }
                        },
                        Collectors.collectingAndThen(
                                Collectors.toList(),
                                assets -> {
                                    if (assets.isEmpty()) {
                                        return null;
                                    }

                                    long count = assets.stream()
                                            .filter(Objects::nonNull)  // 过滤空对象
                                            .map(ZczjStatInfo::getZcjz)  // 获取 zcjz 字段
                                            .filter(Objects::nonNull)  // 过滤空值
                                            .filter(zcjz -> zcjz.compareTo(BigDecimal.ZERO) != 0)  // 过滤为0的值
                                            .count();  // 统计个数
                                    BigDecimal totalAmount = assets.stream()
                                            .map(asset -> {
                                                BigDecimal amount = asset.getZcjz() != null ? asset.getZcjz() : BigDecimal.ZERO;
                                                return amount;
                                            })
                                            .reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP);

                                    try {
                                        assets =assets.stream().filter(asset -> asset.getZcjz() != null).collect(Collectors.toList());
                                        String yearMonth = YearMonth.from(parseDate(assets.get(0).getGxrq())).toString();
                                        return new MonthlyZcrkStat(yearMonth, count, totalAmount);
                                    } catch (Exception e) {
                                        // 解析失败，使用默认值
                                    }
                                    return new MonthlyZcrkStat("invalid", count, totalAmount);
                                }
                        )
                ));

        // 移除无效的分组
        resultMap.remove("invalid");
        resultMap.values().removeIf(Objects::isNull);

        // 确保所有月份都有数据（即使为0）
        List<MonthlyZcrkStat> result = new ArrayList<>();
        YearMonth tempYM = startYM;
        while (!tempYM.isAfter(currentYearMonth)) {
            String yearMonthStr = tempYM.toString();
            if (resultMap.containsKey(yearMonthStr)) {
                MonthlyZcrkStat stat = resultMap.get(yearMonthStr);
                if (stat != null) {
                    result.add(stat);
                } else {
                    result.add(new MonthlyZcrkStat(yearMonthStr, 0, BigDecimal.ZERO));
                }
            } else {
                result.add(new MonthlyZcrkStat(yearMonthStr, 0, BigDecimal.ZERO));
            }
            tempYM = tempYM.plusMonths(1);
        }

        // 按年月排序
        return result.stream()
                .filter(Objects::nonNull)
                .sorted(Comparator.comparing(MonthlyZcrkStat::getYearMonth))
                .collect(Collectors.toList());
    }

    /**
     * 获取指定年度的折旧统计汇总
     */
    public static Map<String, Object> getAnnualDepreciationSummary(List<ZczjStatInfo> list, int year) {
        Map<String, Object> summary = new HashMap<>();

        List<AnnualZcrkStat> annualStats = getAnnualDepreciationStatistics(list);
        AnnualZcrkStat targetYearStat = annualStats.stream()
                .filter(stat -> stat.getYear() == year)
                .findFirst()
                .orElse(new AnnualZcrkStat(year, 0, BigDecimal.ZERO));

        summary.put("year", year);
        summary.put("count", targetYearStat.getCount());
        summary.put("amount", targetYearStat.getAmount());
        summary.put("annualStats", annualStats);

        return summary;
    }

    /**
     * 获取指定年月的折旧统计汇总
     */
    public static Map<String, Object> getMonthlyDepreciationSummary(List<ZczjStatInfo> list, String yearMonth) {
        Map<String, Object> summary = new HashMap<>();

        List<MonthlyZcrkStat> monthlyStats = getMonthlyDepreciationStatistics(list);
        MonthlyZcrkStat targetMonthStat = monthlyStats.stream()
                .filter(stat -> stat.getYearMonth().equals(yearMonth))
                .findFirst()
                .orElse(new MonthlyZcrkStat(yearMonth, 0, BigDecimal.ZERO));

        summary.put("yearMonth", yearMonth);
        summary.put("count", targetMonthStat.getCount());
        summary.put("amount", targetMonthStat.getAmount());
        summary.put("monthlyStats", monthlyStats);

        return summary;
    }

    /**
     * 获取折旧统计汇总信息
     */
    private static Map<String, Object> getDepreciationSummaryInfo(List<ZczjStatInfo> list) {
        Map<String, Object> summary = new HashMap<>();

        if (list == null || list.isEmpty()) {
            summary.put("totalAssetCount", 0);
            summary.put("currentNetValue", BigDecimal.ZERO);
            summary.put("validDataCount", 0);
            return summary;
        }

        // 过滤有效数据
        List<ZczjStatInfo> validAssets = list.stream()
                .filter(ZjStatUtil::isValidAssetDepreciation)
                .collect(Collectors.toList());

        // 获取最新数据（按更新日期排序）
        Optional<ZczjStatInfo> latestData = validAssets.stream()
                .max(Comparator.comparing(asset -> parseDate(asset.getGxrq())));

        BigDecimal currentNetValue = latestData.map(asset ->
                asset.getZcjz() != null ? asset.getZcjz() : BigDecimal.ZERO
        ).orElse(BigDecimal.ZERO);

        summary.put("totalAssetCount", validAssets.size());
        summary.put("currentNetValue", currentNetValue);
        summary.put("validDataCount", validAssets.size());
        summary.put("statTime", LocalDate.now().toString());
        summary.put("latestUpdateDate", latestData.map(asset -> asset.getGxrq()).orElse("无数据"));

        return summary;
    }

    /**
     * 验证资产折旧数据的有效性
     */
    private static boolean isValidAssetDepreciation(ZczjStatInfo asset) {
        if (asset == null) {
            return false;
        }

        // 检查必要字段 - 更新日期和资产净值
        if (asset.getGxrq() == null || asset.getGxrq().trim().isEmpty()) {
            return false;
        }

        if (asset.getZcjz() == null) {
            return false;
        }

        // 验证日期格式
        try {
            parseDate(asset.getGxrq());
        } catch (Exception e) {
            return false;
        }

        return true;
    }

    /**
     * 带缓存的日期解析方法
     */
    private static LocalDate parseDate(String dateStr) {
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return null;
        }

        return DATE_CACHE.computeIfAbsent(dateStr, key -> {
            try {
                return LocalDate.parse(key, DATE_FORMATTER);
            } catch (DateTimeParseException e) {
                throw new RuntimeException("日期格式错误: " + key, e);
            }
        });
    }

    /**
     * 创建空的年度统计
     */
    private static List<AnnualZcrkStat> createEmptyAnnualStats() {
        int currentYear = LocalDate.now().getYear();
        int startYear = currentYear - 8;
        List<AnnualZcrkStat> annualStats = new ArrayList<>();

        for (int year = startYear; year < currentYear; year++) {
            annualStats.add(new AnnualZcrkStat(year, 0, BigDecimal.ZERO));
        }

        return annualStats;
    }

    /**
     * 创建空的月度统计
     */
    private static List<MonthlyZcrkStat> createEmptyMonthlyStats() {
        YearMonth currentYearMonth = YearMonth.now();
        YearMonth startYM = currentYearMonth.minusMonths(11);
        List<MonthlyZcrkStat> monthlyStats = new ArrayList<>();

        YearMonth tempYM = startYM;
        while (!tempYM.isAfter(currentYearMonth)) {
            monthlyStats.add(new MonthlyZcrkStat(tempYM.toString(), 0, BigDecimal.ZERO));
            tempYM = tempYM.plusMonths(1);
        }

        return monthlyStats;
    }

    /**
     * 清空日期缓存
     */
    public static void clearDateCache() {
        DATE_CACHE.clear();
    }

    /**
     * 获取缓存大小（用于监控）
     */
    public static int getCacheSize() {
        return DATE_CACHE.size();
    }
}